home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / doom / knbot03.zip / SRC.ZIP / ITEMS.QC < prev    next >
Text File  |  1996-09-02  |  32KB  |  1,390 lines

  1. void() W_SetCurrentAmmo;
  2. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  3. BE .8 .3 .4 IN COLOR */
  4.  
  5.  
  6. void() SUB_regen =
  7. {
  8.     self.model = self.mdl;        // restore original model
  9.     self.solid = SOLID_TRIGGER;    // allow it to be touched again
  10.     sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  11.     setorigin (self, self.origin);
  12. };
  13.  
  14.  
  15.  
  16. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  17. prints a warning message when spawned
  18. */
  19. void() noclass =
  20. {
  21.     dprint ("noclass spawned at");
  22.     dprint (vtos(self.origin));
  23.     dprint ("\n");
  24.     remove (self);
  25. };
  26.  
  27.  
  28.  
  29. /*
  30. ============
  31. PlaceItem
  32.  
  33. plants the object on the floor
  34. ============
  35. */
  36. void() PlaceItem =
  37. {
  38.     local float    oldz;
  39.  
  40.     self.mdl = self.model;        // so it can be restored on respawn
  41.     self.flags = FL_ITEM;        // make extra wide
  42.     self.solid = SOLID_TRIGGER;
  43.     self.movetype = MOVETYPE_TOSS;    
  44.     self.velocity = '0 0 0';
  45.     self.origin_z = self.origin_z + 6;
  46.     oldz = self.origin_z;
  47.     if (!droptofloor())
  48.     {
  49.         dprint ("Bonus item fell out of level at ");
  50.         dprint (vtos(self.origin));
  51.         dprint ("\n");
  52.         remove(self);
  53.         return;
  54.     }
  55. };
  56.  
  57. /*
  58. ============
  59. StartItem
  60.  
  61. Sets the clipping size and plants the object on the floor
  62. ============
  63. */
  64. void() StartItem =
  65. {
  66.     self.nextthink = time + 0.2;    // items start after other solids
  67.     self.think = PlaceItem;
  68. };
  69.  
  70. /*
  71. =========================================================================
  72.  
  73. HEALTH BOX
  74.  
  75. =========================================================================
  76. */
  77. //
  78. // T_Heal: add health to an entity, limiting health to max_health
  79. // "ignore" will ignore max_health limit
  80. //
  81. float (entity e, float healamount, float ignore) T_Heal =
  82. {
  83.     if (e.health <= 0)
  84.         return 0;
  85.     if ((!ignore) && (e.health >= other.max_health))
  86.         return 0;
  87.     healamount = ceil(healamount);
  88.  
  89.     e.health = e.health + healamount;
  90.     if ((!ignore) && (e.health >= other.max_health))
  91.         e.health = other.max_health;
  92.         
  93.     if (e.health > 250)
  94.         e.health = 250;
  95.     return 1;
  96. };
  97.  
  98. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  99. Health box. Normally gives 25 points.
  100. Rotten box heals 5-10 points,
  101. megahealth will add 100 health, then 
  102. rot you down to your maximum health limit, 
  103. one point per second.
  104. */
  105.  
  106. float    H_ROTTEN = 1;
  107. float    H_MEGA = 2;
  108. .float    healamount, healtype;
  109. void() health_touch;
  110. void() item_megahealth_rot;
  111.  
  112. void() item_health =
  113. {    
  114.     self.touch = health_touch;
  115.  
  116.     if (self.spawnflags & H_ROTTEN)
  117.     {
  118.         precache_model("maps/b_bh10.bsp");
  119.  
  120.         precache_sound("items/r_item1.wav");
  121.         setmodel(self, "maps/b_bh10.bsp");
  122.         self.noise = "items/r_item1.wav";
  123.         self.healamount = 15;
  124.         self.healtype = 0;
  125.     }
  126.     else
  127.     if (self.spawnflags & H_MEGA)
  128.     {
  129.         precache_model("maps/b_bh100.bsp");
  130.         precache_sound("items/r_item2.wav");
  131.         setmodel(self, "maps/b_bh100.bsp");
  132.         self.noise = "items/r_item2.wav";
  133.         self.healamount = 100;
  134.         self.healtype = 2;
  135.     }
  136.     else
  137.     {
  138.         precache_model("maps/b_bh25.bsp");
  139.         precache_sound("items/health1.wav");
  140.         setmodel(self, "maps/b_bh25.bsp");
  141.         self.noise = "items/health1.wav";
  142.         self.healamount = 25;
  143.         self.healtype = 1;
  144.     }
  145.     setsize (self, '0 0 0', '32 32 56');
  146.     StartItem ();
  147. };
  148.  
  149.  
  150. void() health_touch =
  151. {
  152.     local    float amount;
  153.     local    string    s;
  154.     
  155.         if (other.classname != "player" && other.classname != "bot")
  156.         return;
  157.     
  158.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  159.     {
  160.         if (other.health >= 250)
  161.             return;
  162.         if (!T_Heal(other, self.healamount, 1))
  163.             return;
  164.     }
  165.     else
  166.     {
  167.         if (!T_Heal(other, self.healamount, 0))
  168.             return;
  169.     }
  170.     
  171.         if (other.classname == "player")
  172.         {
  173.                 sprint(other, "You receive ");
  174.                 s = ftos(self.healamount);
  175.                 sprint(other, s);
  176.                 sprint(other, " health\n");
  177.     
  178. // health touch sound
  179.                 sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  180.                 stuffcmd (other, "bf\n");
  181.         }
  182.  
  183.     self.model = string_null;
  184.     self.solid = SOLID_NOT;
  185.  
  186.     // Megahealth = rot down the player's super health
  187.     if (self.healtype == 2)
  188.     {
  189.         other.items = other.items | IT_SUPERHEALTH;
  190.         self.nextthink = time + 5;
  191.         self.think = item_megahealth_rot;
  192.         self.owner = other;
  193.     }
  194.     else
  195.     {
  196.         if (deathmatch != 2)        // deathmatch 2 is the silly old rules
  197.         {
  198.             if (deathmatch)
  199.                 self.nextthink = time + 20;
  200.             self.think = SUB_regen;
  201.         }
  202.     }
  203.     
  204.     activator = other;
  205.     SUB_UseTargets();                // fire all targets / killtargets
  206. };    
  207.  
  208. void() item_megahealth_rot =
  209. {
  210.     other = self.owner;
  211.     
  212.     if (other.health > other.max_health)
  213.     {
  214.         other.health = other.health - 1;
  215.         self.nextthink = time + 1;
  216.         return;
  217.     }
  218.  
  219. // it is possible for a player to die and respawn between rots, so don't
  220. // just blindly subtract the flag off
  221.     other.items = other.items - (other.items & IT_SUPERHEALTH);
  222.     
  223.     if (deathmatch == 1)    // deathmatch 2 is silly old rules
  224.     {
  225.         self.nextthink = time + 20;
  226.         self.think = SUB_regen;
  227.     }
  228. };
  229.  
  230. /*
  231. ===============================================================================
  232.  
  233. ARMOR
  234.  
  235. ===============================================================================
  236. */
  237.  
  238. void() armor_touch;
  239.  
  240. void() armor_touch =
  241. {
  242.     local    float    type, value, bit;
  243.     
  244.     if (other.health <= 0)
  245.         return;
  246.         if (other.classname != "player" && other.classname != "bot")
  247.         return;
  248.  
  249.     if (self.classname == "item_armor1")
  250.     {
  251.         type = 0.3;
  252.         value = 100;
  253.         bit = IT_ARMOR1;
  254.     }
  255.     if (self.classname == "item_armor2")
  256.     {
  257.         type = 0.6;
  258.         value = 150;
  259.         bit = IT_ARMOR2;
  260.     }
  261.     if (self.classname == "item_armorInv")
  262.     {
  263.         type = 0.8;
  264.         value = 200;
  265.         bit = IT_ARMOR3;
  266.     }
  267.     if (other.armortype*other.armorvalue >= type*value)
  268.         return;
  269.         
  270.     other.armortype = type;
  271.     other.armorvalue = value;
  272.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  273.  
  274.     self.solid = SOLID_NOT;
  275.     self.model = string_null;
  276.     if (deathmatch == 1)
  277.         self.nextthink = time + 20;
  278.     self.think = SUB_regen;
  279.  
  280.         if (other.classname == "player")
  281.         {
  282.                 sprint(other, "You got armor\n");
  283. // armor touch sound
  284.                 sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  285.                 stuffcmd (other, "bf\n");
  286.         }
  287.     activator = other;
  288.     SUB_UseTargets();                // fire all targets / killtargets
  289. };
  290.  
  291.  
  292. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  293. */
  294.  
  295. void() item_armor1 =
  296. {
  297.     self.touch = armor_touch;
  298.     precache_model ("progs/armor.mdl");
  299.     setmodel (self, "progs/armor.mdl");
  300.     self.skin = 0;
  301.     setsize (self, '-16 -16 0', '16 16 56');
  302.     StartItem ();
  303. };
  304.  
  305. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  306. */
  307.  
  308. void() item_armor2 =
  309. {
  310.     self.touch = armor_touch;
  311.     precache_model ("progs/armor.mdl");
  312.     setmodel (self, "progs/armor.mdl");
  313.     self.skin = 1;
  314.     setsize (self, '-16 -16 0', '16 16 56');
  315.     StartItem ();
  316. };
  317.  
  318. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  319. */
  320.  
  321. void() item_armorInv =
  322. {
  323.     self.touch = armor_touch;
  324.     precache_model ("progs/armor.mdl");
  325.     setmodel (self, "progs/armor.mdl");
  326.     self.skin = 2;
  327.     setsize (self, '-16 -16 0', '16 16 56');
  328.     StartItem ();
  329. };
  330.  
  331. /*
  332. ===============================================================================
  333.  
  334. WEAPONS
  335.  
  336. ===============================================================================
  337. */
  338.  
  339. void() bound_other_ammo =
  340. {
  341.     if (other.ammo_shells > 100)
  342.         other.ammo_shells = 100;
  343.     if (other.ammo_nails > 200)
  344.         other.ammo_nails = 200;
  345.     if (other.ammo_rockets > 100)
  346.         other.ammo_rockets = 100;        
  347.     if (other.ammo_cells > 100)
  348.         other.ammo_cells = 100;        
  349. };
  350.  
  351.  
  352. float(float w) RankForWeapon =
  353. {
  354.     if (w == IT_LIGHTNING)
  355.         return 1;
  356.     if (w == IT_ROCKET_LAUNCHER)
  357.         return 2;
  358.     if (w == IT_SUPER_NAILGUN)
  359.         return 3;
  360.     if (w == IT_GRENADE_LAUNCHER)
  361.         return 4;
  362.     if (w == IT_SUPER_SHOTGUN)
  363.         return 5;
  364.     if (w == IT_NAILGUN)
  365.         return 6;
  366.     return 7;
  367. };
  368.  
  369. /*
  370. =============
  371. Deathmatch_Weapon
  372.  
  373. Deathmatch weapon change rules for picking up a weapon
  374.  
  375. .float        ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  376. =============
  377. */
  378. void(float old, float new) Deathmatch_Weapon =
  379. {
  380.     local float or, nr;
  381.  
  382. // change self.weapon if desired
  383.     or = RankForWeapon (self.weapon);
  384.     nr = RankForWeapon (new);
  385.     if ( nr < or )
  386.         self.weapon = new;
  387. };
  388.  
  389. /*
  390. =============
  391. weapon_touch
  392. =============
  393. */
  394. float() W_BestWeapon;
  395. void() weapon_touch =
  396. {
  397.         local   float   hadammo, best, new, old, bbest;
  398.     local    entity    stemp;
  399.     local    float    leave;
  400.  
  401.         if (!(other.flags & FL_CLIENT) && other.classname != "bot")
  402.         return;
  403.  
  404. // if the player was using his best weapon, change up to the new one if better        
  405.     stemp = self;
  406.     self = other;
  407.     best = W_BestWeapon();
  408.         bbest = bot_bestweapon();
  409.     self = stemp;
  410.  
  411.     if (deathmatch == 2 || coop)
  412.         leave = 1;
  413.     else
  414.         leave = 0;
  415.     
  416.     if (self.classname == "weapon_nailgun")
  417.     {
  418.         if (leave && (other.items & IT_NAILGUN) )
  419.             return;
  420.         hadammo = other.ammo_nails;            
  421.         new = IT_NAILGUN;
  422.         other.ammo_nails = other.ammo_nails + 30;
  423.     }
  424.     else if (self.classname == "weapon_supernailgun")
  425.     {
  426.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  427.             return;
  428.         hadammo = other.ammo_rockets;            
  429.         new = IT_SUPER_NAILGUN;
  430.         other.ammo_nails = other.ammo_nails + 30;
  431.     }
  432.     else if (self.classname == "weapon_supershotgun")
  433.     {
  434.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  435.             return;
  436.         hadammo = other.ammo_rockets;            
  437.         new = IT_SUPER_SHOTGUN;
  438.         other.ammo_shells = other.ammo_shells + 5;
  439.     }
  440.     else if (self.classname == "weapon_rocketlauncher")
  441.     {
  442.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  443.             return;
  444.         hadammo = other.ammo_rockets;            
  445.         new = IT_ROCKET_LAUNCHER;
  446.         other.ammo_rockets = other.ammo_rockets + 5;
  447.     }
  448.     else if (self.classname == "weapon_grenadelauncher")
  449.     {
  450.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  451.             return;
  452.         hadammo = other.ammo_rockets;            
  453.         new = IT_GRENADE_LAUNCHER;
  454.         other.ammo_rockets = other.ammo_rockets + 5;
  455.     }
  456.     else if (self.classname == "weapon_lightning")
  457.     {
  458.         if (leave && (other.items & IT_LIGHTNING) )
  459.             return;
  460.         hadammo = other.ammo_rockets;            
  461.         new = IT_LIGHTNING;
  462.         other.ammo_cells = other.ammo_cells + 15;
  463.     }
  464.     else
  465.         objerror ("weapon_touch: unknown classname");
  466.  
  467.         if (other.classname == "player")
  468.         {
  469.                 sprint (other, "You got the ");
  470.                 sprint (other, self.netname);
  471.                 sprint (other, "\n");
  472. // weapon touch sound
  473.                 sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  474.                 stuffcmd (other, "bf\n");
  475.  
  476.         }
  477.     bound_other_ammo ();
  478.  
  479. // change to the weapon
  480.     old = other.items;
  481.     other.items = other.items | new;
  482.     
  483.     stemp = self;
  484.     self = other;
  485.  
  486.     if (!deathmatch)
  487.         self.weapon = new;
  488.     else
  489.         Deathmatch_Weapon (old, new);
  490.  
  491.         if (other.classname == "player")
  492.                 W_SetCurrentAmmo();
  493.  
  494.         if (other.classname == "bot")
  495.                 bot_SetCurrentAmmo();
  496.  
  497.     self = stemp;
  498.  
  499.     if (leave)
  500.         return;
  501.  
  502. // remove it in single player, or setup for respawning in deathmatch
  503.     self.model = string_null;
  504.     self.solid = SOLID_NOT;
  505.     if (deathmatch == 1)
  506.         self.nextthink = time + 30;
  507.     self.think = SUB_regen;
  508.     
  509.     activator = other;
  510.     SUB_UseTargets();                // fire all targets / killtargets
  511. };
  512.  
  513.  
  514. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  515. */
  516.  
  517. void() weapon_supershotgun =
  518. {
  519.     precache_model ("progs/g_shot.mdl");
  520.     setmodel (self, "progs/g_shot.mdl");
  521.     self.weapon = IT_SUPER_SHOTGUN;
  522.     self.netname = "Double-barrelled Shotgun";
  523.     self.touch = weapon_touch;
  524.     setsize (self, '-16 -16 0', '16 16 56');
  525.     StartItem ();
  526. };
  527.  
  528. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  529. */
  530.  
  531. void() weapon_nailgun =
  532. {
  533.     precache_model ("progs/g_nail.mdl");
  534.     setmodel (self, "progs/g_nail.mdl");
  535.     self.weapon = IT_NAILGUN;
  536.     self.netname = "nailgun";
  537.     self.touch = weapon_touch;
  538.     setsize (self, '-16 -16 0', '16 16 56');
  539.     StartItem ();
  540. };
  541.  
  542. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  543. */
  544.  
  545. void() weapon_supernailgun =
  546. {
  547.     precache_model ("progs/g_nail2.mdl");
  548.     setmodel (self, "progs/g_nail2.mdl");
  549.     self.weapon = IT_SUPER_NAILGUN;
  550.     self.netname = "Super Nailgun";
  551.     self.touch = weapon_touch;
  552.     setsize (self, '-16 -16 0', '16 16 56');
  553.     StartItem ();
  554. };
  555.  
  556. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  557. */
  558.  
  559. void() weapon_grenadelauncher =
  560. {
  561.     precache_model ("progs/g_rock.mdl");
  562.     setmodel (self, "progs/g_rock.mdl");
  563.     self.weapon = 3;
  564.     self.netname = "Grenade Launcher";
  565.     self.touch = weapon_touch;
  566.     setsize (self, '-16 -16 0', '16 16 56');
  567.     StartItem ();
  568. };
  569.  
  570. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  571. */
  572.  
  573. void() weapon_rocketlauncher =
  574. {
  575.     precache_model ("progs/g_rock2.mdl");
  576.     setmodel (self, "progs/g_rock2.mdl");
  577.     self.weapon = 3;
  578.     self.netname = "Rocket Launcher";
  579.     self.touch = weapon_touch;
  580.     setsize (self, '-16 -16 0', '16 16 56');
  581.     StartItem ();
  582. };
  583.  
  584.  
  585. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  586. */
  587.  
  588. void() weapon_lightning =
  589. {
  590.     precache_model ("progs/g_light.mdl");
  591.     setmodel (self, "progs/g_light.mdl");
  592.     self.weapon = 3;
  593.     self.netname = "Thunderbolt";
  594.     self.touch = weapon_touch;
  595.     setsize (self, '-16 -16 0', '16 16 56');
  596.     StartItem ();
  597. };
  598.  
  599.  
  600. /*
  601. ===============================================================================
  602.  
  603. AMMO
  604.  
  605. ===============================================================================
  606. */
  607.  
  608. void() ammo_touch =
  609. {
  610. local entity    stemp;
  611. local float             best, bbest;
  612.  
  613.         if (other.classname != "player" && other.classname != "bot")
  614.         return;
  615.     if (other.health <= 0)
  616.         return;
  617.  
  618. // if the player was using his best weapon, change up to the new one if better        
  619.     stemp = self;
  620.     self = other;
  621.     best = W_BestWeapon();
  622.         bbest = bot_bestweapon();
  623.     self = stemp;
  624.  
  625.  
  626. // shotgun
  627.     if (self.weapon == 1)
  628.     {
  629.         if (other.ammo_shells >= 100)
  630.             return;
  631.         other.ammo_shells = other.ammo_shells + self.aflag;
  632.     }
  633.  
  634. // spikes
  635.     if (self.weapon == 2)
  636.     {
  637.         if (other.ammo_nails >= 200)
  638.             return;
  639.         other.ammo_nails = other.ammo_nails + self.aflag;
  640.     }
  641.  
  642. //    rockets
  643.     if (self.weapon == 3)
  644.     {
  645.         if (other.ammo_rockets >= 100)
  646.             return;
  647.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  648.     }
  649.  
  650. //    cells
  651.     if (self.weapon == 4)
  652.     {
  653.         if (other.ammo_cells >= 200)
  654.             return;
  655.         other.ammo_cells = other.ammo_cells + self.aflag;
  656.     }
  657.  
  658.     bound_other_ammo ();
  659.     
  660.         if (other.classname == "player")
  661.         {
  662.                 sprint (other, "You got the ");
  663.                 sprint (other, self.netname);
  664.                 sprint (other, "\n");
  665. // ammo touch sound
  666.                 sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  667.                 stuffcmd (other, "bf\n");
  668. // change to a better weapon if appropriate
  669.  
  670.                 if ( other.weapon == best )
  671.                 {
  672.                         stemp = self;
  673.                         self = other;
  674.                         self.weapon = W_BestWeapon();
  675.                         W_SetCurrentAmmo ();
  676.                         self = stemp;
  677.                 }
  678.                 stemp = self;
  679.                 self = other;
  680.                 W_SetCurrentAmmo();
  681.                 self = stemp;
  682.         }
  683.         if (other.classname == "bot")
  684.         {
  685.                 if ( other.weapon == bbest )
  686.                 {
  687.                         stemp = self;
  688.                         self = other;
  689.                         self.weapon = bot_bestweapon();
  690.                         bot_SetCurrentAmmo ();
  691.                         self = stemp;
  692.                 }
  693.                 stemp = self;
  694.                 self = other;
  695.                 bot_SetCurrentAmmo();
  696.                 self = stemp;
  697.         }
  698.  
  699.     self.model = string_null;
  700.     self.solid = SOLID_NOT;
  701.     if (deathmatch == 1)
  702.         self.nextthink = time + 30;
  703.     
  704.     self.think = SUB_regen;
  705.  
  706.     activator = other;
  707.     SUB_UseTargets();                // fire all targets / killtargets
  708. };
  709.  
  710.  
  711.  
  712.  
  713. float WEAPON_BIG2 = 1;
  714.  
  715. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  716. */
  717.  
  718. void() item_shells =
  719. {
  720.     self.touch = ammo_touch;
  721.  
  722.     if (self.spawnflags & WEAPON_BIG2)
  723.     {
  724.         precache_model ("maps/b_shell1.bsp");
  725.         setmodel (self, "maps/b_shell1.bsp");
  726.         self.aflag = 40;
  727.     }
  728.     else
  729.     {
  730.         precache_model ("maps/b_shell0.bsp");
  731.         setmodel (self, "maps/b_shell0.bsp");
  732.         self.aflag = 20;
  733.     }
  734.     self.weapon = 1;
  735.         self.classname = "botshells";
  736.     self.netname = "shells";
  737.     setsize (self, '0 0 0', '32 32 56');
  738.     StartItem ();
  739. };
  740.  
  741. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  742. */
  743.  
  744. void() item_spikes =
  745. {
  746.     self.touch = ammo_touch;
  747.  
  748.     if (self.spawnflags & WEAPON_BIG2)
  749.     {
  750.         precache_model ("maps/b_nail1.bsp");
  751.         setmodel (self, "maps/b_nail1.bsp");
  752.         self.aflag = 50;
  753.     }
  754.     else
  755.     {
  756.         precache_model ("maps/b_nail0.bsp");
  757.         setmodel (self, "maps/b_nail0.bsp");
  758.         self.aflag = 25;
  759.     }
  760.     self.weapon = 2;
  761.         self.classname = "botnails";
  762.     self.netname = "nails";
  763.     setsize (self, '0 0 0', '32 32 56');
  764.     StartItem ();
  765. };
  766.  
  767. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  768. */
  769.  
  770. void() item_rockets =
  771. {
  772.     self.touch = ammo_touch;
  773.  
  774.     if (self.spawnflags & WEAPON_BIG2)
  775.     {
  776.         precache_model ("maps/b_rock1.bsp");
  777.         setmodel (self, "maps/b_rock1.bsp");
  778.         self.aflag = 10;
  779.     }
  780.     else
  781.     {
  782.         precache_model ("maps/b_rock0.bsp");
  783.         setmodel (self, "maps/b_rock0.bsp");
  784.         self.aflag = 5;
  785.     }
  786.     self.weapon = 3;
  787.         self.classname = "botrock";
  788.     self.netname = "rockets";
  789.     setsize (self, '0 0 0', '32 32 56');
  790.     StartItem ();
  791. };
  792.  
  793.  
  794. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  795. */
  796.  
  797. void() item_cells =
  798. {
  799.     self.touch = ammo_touch;
  800.  
  801.     if (self.spawnflags & WEAPON_BIG2)
  802.     {
  803.         precache_model ("maps/b_batt1.bsp");
  804.         setmodel (self, "maps/b_batt1.bsp");
  805.         self.aflag = 12;
  806.     }
  807.     else
  808.     {
  809.         precache_model ("maps/b_batt0.bsp");
  810.         setmodel (self, "maps/b_batt0.bsp");
  811.         self.aflag = 6;
  812.     }
  813.     self.weapon = 4;
  814.     self.netname = "cells";
  815.     setsize (self, '0 0 0', '32 32 56');
  816.     StartItem ();
  817. };
  818.  
  819.  
  820. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  821. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  822. */
  823.  
  824. float WEAPON_SHOTGUN = 1;
  825. float WEAPON_ROCKET = 2;
  826. float WEAPON_SPIKES = 4;
  827. float WEAPON_BIG = 8;
  828. void() item_weapon =
  829. {
  830.     self.touch = ammo_touch;
  831.  
  832.     if (self.spawnflags & WEAPON_SHOTGUN)
  833.     {
  834.         if (self.spawnflags & WEAPON_BIG)
  835.         {
  836.             precache_model ("maps/b_shell1.bsp");
  837.             setmodel (self, "maps/b_shell1.bsp");
  838.             self.aflag = 40;
  839.         }
  840.         else
  841.         {
  842.             precache_model ("maps/b_shell0.bsp");
  843.             setmodel (self, "maps/b_shell0.bsp");
  844.             self.aflag = 20;
  845.         }
  846.         self.weapon = 1;
  847.         self.netname = "shells";
  848.     }
  849.  
  850.     if (self.spawnflags & WEAPON_SPIKES)
  851.     {
  852.         if (self.spawnflags & WEAPON_BIG)
  853.         {
  854.             precache_model ("maps/b_nail1.bsp");
  855.             setmodel (self, "maps/b_nail1.bsp");
  856.             self.aflag = 40;
  857.         }
  858.         else
  859.         {
  860.             precache_model ("maps/b_nail0.bsp");
  861.             setmodel (self, "maps/b_nail0.bsp");
  862.             self.aflag = 20;
  863.         }
  864.         self.weapon = 2;
  865.         self.netname = "spikes";
  866.     }
  867.  
  868.     if (self.spawnflags & WEAPON_ROCKET)
  869.     {
  870.         if (self.spawnflags & WEAPON_BIG)
  871.         {
  872.             precache_model ("maps/b_rock1.bsp");
  873.             setmodel (self, "maps/b_rock1.bsp");
  874.             self.aflag = 10;
  875.         }
  876.         else
  877.         {
  878.             precache_model ("maps/b_rock0.bsp");
  879.             setmodel (self, "maps/b_rock0.bsp");
  880.             self.aflag = 5;
  881.         }
  882.         self.weapon = 3;
  883.         self.netname = "rockets";
  884.     }
  885.     
  886.     setsize (self, '0 0 0', '32 32 56');
  887.     StartItem ();
  888. };
  889.  
  890.  
  891. /*
  892. ===============================================================================
  893.  
  894. KEYS
  895.  
  896. ===============================================================================
  897. */
  898.  
  899. void() key_touch =
  900. {
  901. local entity    stemp;
  902. local float        best;
  903.  
  904.     if (other.classname != "player")
  905.         return;
  906.     if (other.health <= 0)
  907.         return;
  908.     if (other.items & self.items)
  909.         return;
  910.  
  911.     sprint (other, "You got the ");
  912.     sprint (other, self.netname);
  913.     sprint (other,"\n");
  914.  
  915.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  916.     stuffcmd (other, "bf\n");
  917.     other.items = other.items | self.items;
  918.  
  919.     if (!coop)
  920.     {    
  921.         self.solid = SOLID_NOT;
  922.         self.model = string_null;
  923.     }
  924.  
  925.     activator = other;
  926.     SUB_UseTargets();                // fire all targets / killtargets
  927. };
  928.  
  929.  
  930. void() key_setsounds =
  931. {
  932.     if (world.worldtype == 0)
  933.     {
  934.         precache_sound ("misc/medkey.wav");
  935.         self.noise = "misc/medkey.wav";
  936.     }
  937.     if (world.worldtype == 1)
  938.     {
  939.         precache_sound ("misc/runekey.wav");
  940.         self.noise = "misc/runekey.wav";
  941.     }
  942.     if (world.worldtype == 2)
  943.     {
  944.         precache_sound2 ("misc/basekey.wav");
  945.         self.noise = "misc/basekey.wav";
  946.     }
  947. };
  948.  
  949. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  950. SILVER key
  951. In order for keys to work
  952. you MUST set your maps
  953. worldtype to one of the
  954. following:
  955. 0: medieval
  956. 1: metal
  957. 2: base
  958. */
  959.  
  960. void() item_key1 =
  961. {
  962.     if (world.worldtype == 0)
  963.     {
  964.         precache_model ("progs/w_s_key.mdl");
  965.         setmodel (self, "progs/w_s_key.mdl");
  966.         self.netname = "silver key";
  967.     }
  968.     else if (world.worldtype == 1)
  969.     {
  970.         precache_model ("progs/m_s_key.mdl");
  971.         setmodel (self, "progs/m_s_key.mdl");
  972.         self.netname = "silver runekey";
  973.     }
  974.     else if (world.worldtype == 2)
  975.     {
  976.         precache_model2 ("progs/b_s_key.mdl");
  977.         setmodel (self, "progs/b_s_key.mdl");
  978.         self.netname = "silver keycard";
  979.     }
  980.     key_setsounds();
  981.     self.touch = key_touch;
  982.     self.items = IT_KEY1;
  983.     setsize (self, '-16 -16 -24', '16 16 32');
  984.     StartItem ();
  985. };
  986.  
  987. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  988. GOLD key
  989. In order for keys to work
  990. you MUST set your maps
  991. worldtype to one of the
  992. following:
  993. 0: medieval
  994. 1: metal
  995. 2: base
  996. */
  997.  
  998. void() item_key2 =
  999. {
  1000.     if (world.worldtype == 0)
  1001.     {
  1002.         precache_model ("progs/w_g_key.mdl");
  1003.         setmodel (self, "progs/w_g_key.mdl");
  1004.         self.netname = "gold key";
  1005.     }
  1006.     if (world.worldtype == 1)
  1007.     {
  1008.         precache_model ("progs/m_g_key.mdl");
  1009.         setmodel (self, "progs/m_g_key.mdl");
  1010.         self.netname = "gold runekey";
  1011.     }
  1012.     if (world.worldtype == 2)
  1013.     {
  1014.         precache_model2 ("progs/b_g_key.mdl");
  1015.         setmodel (self, "progs/b_g_key.mdl");
  1016.         self.netname = "gold keycard";
  1017.     }
  1018.     key_setsounds();
  1019.     self.touch = key_touch;
  1020.     self.items = IT_KEY2;
  1021.     setsize (self, '-16 -16 -24', '16 16 32');
  1022.     StartItem ();
  1023. };
  1024.  
  1025.  
  1026.  
  1027. /*
  1028. ===============================================================================
  1029.  
  1030. END OF LEVEL RUNES
  1031.  
  1032. ===============================================================================
  1033. */
  1034.  
  1035. void() sigil_touch =
  1036. {
  1037. local entity    stemp;
  1038. local float        best;
  1039.  
  1040.     if (other.classname != "player")
  1041.         return;
  1042.     if (other.health <= 0)
  1043.         return;
  1044.  
  1045.     centerprint (other, "You got the rune!");
  1046.  
  1047.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1048.     stuffcmd (other, "bf\n");
  1049.     self.solid = SOLID_NOT;
  1050.     self.model = string_null;
  1051.     serverflags = serverflags | (self.spawnflags & 15);
  1052.     self.classname = "";        // so rune doors won't find it
  1053.     
  1054.     activator = other;
  1055.     SUB_UseTargets();                // fire all targets / killtargets
  1056. };
  1057.  
  1058.  
  1059. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1060. End of level sigil, pick up to end episode and return to jrstart.
  1061. */
  1062.  
  1063. void() item_sigil =
  1064. {
  1065.     if (!self.spawnflags)
  1066.         objerror ("no spawnflags");
  1067.  
  1068.     precache_sound ("misc/runekey.wav");
  1069.     self.noise = "misc/runekey.wav";
  1070.  
  1071.     if (self.spawnflags & 1)
  1072.     {
  1073.         precache_model ("progs/end1.mdl");
  1074.         setmodel (self, "progs/end1.mdl");
  1075.     }
  1076.     if (self.spawnflags & 2)
  1077.     {
  1078.         precache_model2 ("progs/end2.mdl");
  1079.         setmodel (self, "progs/end2.mdl");
  1080.     }
  1081.     if (self.spawnflags & 4)
  1082.     {
  1083.         precache_model2 ("progs/end3.mdl");
  1084.         setmodel (self, "progs/end3.mdl");
  1085.     }
  1086.     if (self.spawnflags & 8)
  1087.     {
  1088.         precache_model2 ("progs/end4.mdl");
  1089.         setmodel (self, "progs/end4.mdl");
  1090.     }
  1091.     
  1092.     self.touch = sigil_touch;
  1093.     setsize (self, '-16 -16 -24', '16 16 32');
  1094.     StartItem ();
  1095. };
  1096.  
  1097. /*
  1098. ===============================================================================
  1099.  
  1100. POWERUPS
  1101.  
  1102. ===============================================================================
  1103. */
  1104.  
  1105. void() powerup_touch;
  1106.  
  1107.  
  1108. void() powerup_touch =
  1109. {
  1110. local entity    stemp;
  1111. local float        best;
  1112.  
  1113.     if (other.classname != "player")
  1114.         return;
  1115.     if (other.health <= 0)
  1116.         return;
  1117.  
  1118.     sprint (other, "You got the ");
  1119.     sprint (other, self.netname);
  1120.     sprint (other,"\n");
  1121.  
  1122.     if (deathmatch)
  1123.     {
  1124.         self.mdl = self.model;
  1125.         
  1126.         if ((self.classname == "item_artifact_invulnerability") ||
  1127.             (self.classname == "item_artifact_invisibility"))
  1128.             self.nextthink = time + 60*5;
  1129.         else
  1130.             self.nextthink = time + 60;
  1131.         
  1132.         self.think = SUB_regen;
  1133.     }    
  1134.  
  1135.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1136.     stuffcmd (other, "bf\n");
  1137.     self.solid = SOLID_NOT;
  1138.     other.items = other.items | self.items;
  1139.     self.model = string_null;
  1140.  
  1141. // do the apropriate action
  1142.     if (self.classname == "item_artifact_envirosuit")
  1143.     {
  1144.         other.rad_time = 1;
  1145.         other.radsuit_finished = time + 30;
  1146.     }
  1147.     
  1148.     if (self.classname == "item_artifact_invulnerability")
  1149.     {
  1150.         other.invincible_time = 1;
  1151.         other.invincible_finished = time + 30;
  1152.     }
  1153.     
  1154.     if (self.classname == "item_artifact_invisibility")
  1155.     {
  1156.         other.invisible_time = 1;
  1157.         other.invisible_finished = time + 30;
  1158.     }
  1159.  
  1160.     if (self.classname == "item_artifact_super_damage")
  1161.     {
  1162.         other.super_time = 1;
  1163.         other.super_damage_finished = time + 30;
  1164.     }    
  1165.  
  1166.     activator = other;
  1167.     SUB_UseTargets();                // fire all targets / killtargets
  1168. };
  1169.  
  1170.  
  1171.  
  1172. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1173. Player is invulnerable for 30 seconds
  1174. */
  1175. void() item_artifact_invulnerability =
  1176. {
  1177.     self.touch = powerup_touch;
  1178.  
  1179.     precache_model ("progs/invulner.mdl");
  1180.     precache_sound ("items/protect.wav");
  1181.     precache_sound ("items/protect2.wav");
  1182.     precache_sound ("items/protect3.wav");
  1183.     self.noise = "items/protect.wav";
  1184.     setmodel (self, "progs/invulner.mdl");
  1185.     self.netname = "Pentagram of Protection";
  1186.     self.items = IT_INVULNERABILITY;
  1187.     setsize (self, '-16 -16 -24', '16 16 32');
  1188.     StartItem ();
  1189. };
  1190.  
  1191. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1192. Player takes no damage from water or slime for 30 seconds
  1193. */
  1194. void() item_artifact_envirosuit =
  1195. {
  1196.     self.touch = powerup_touch;
  1197.  
  1198.     precache_model ("progs/suit.mdl");
  1199.     precache_sound ("items/suit.wav");
  1200.     precache_sound ("items/suit2.wav");
  1201.     self.noise = "items/suit.wav";
  1202.     setmodel (self, "progs/suit.mdl");
  1203.     self.netname = "Biosuit";
  1204.     self.items = IT_SUIT;
  1205.     setsize (self, '-16 -16 -24', '16 16 32');
  1206.     StartItem ();
  1207. };
  1208.  
  1209.  
  1210. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1211. Player is invisible for 30 seconds
  1212. */
  1213. void() item_artifact_invisibility =
  1214. {
  1215.     self.touch = powerup_touch;
  1216.  
  1217.     precache_model ("progs/invisibl.mdl");
  1218.     precache_sound ("items/inv1.wav");
  1219.     precache_sound ("items/inv2.wav");
  1220.     precache_sound ("items/inv3.wav");
  1221.     self.noise = "items/inv1.wav";
  1222.     setmodel (self, "progs/invisibl.mdl");
  1223.     self.netname = "Ring of Shadows";
  1224.     self.items = IT_INVISIBILITY;
  1225.     setsize (self, '-16 -16 -24', '16 16 32');
  1226.     StartItem ();
  1227. };
  1228.  
  1229.  
  1230. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1231. The next attack from the player will do 4x damage
  1232. */
  1233. void() item_artifact_super_damage =
  1234. {
  1235.     self.touch = powerup_touch;
  1236.  
  1237.     precache_model ("progs/quaddama.mdl");
  1238.     precache_sound ("items/damage.wav");
  1239.     precache_sound ("items/damage2.wav");
  1240.     precache_sound ("items/damage3.wav");
  1241.     self.noise = "items/damage.wav";
  1242.     setmodel (self, "progs/quaddama.mdl");
  1243.     self.netname = "Quad Damage";
  1244.     self.items = IT_QUAD;
  1245.     setsize (self, '-16 -16 -24', '16 16 32');
  1246.     StartItem ();
  1247. };
  1248.  
  1249.  
  1250.  
  1251. /*
  1252. ===============================================================================
  1253.  
  1254. PLAYER BACKPACKS
  1255.  
  1256. ===============================================================================
  1257. */
  1258.  
  1259. void() BackpackTouch =
  1260. {
  1261.     local string    s;
  1262.         local   float   best, bbest;
  1263.     local        entity    stemp;
  1264.     
  1265.         if (other.classname != "player" && other.classname != "bot")
  1266.         return;
  1267.     if (other.health <= 0)
  1268.         return;
  1269.         
  1270. // if the player was using his best weapon, change up to the new one if better        
  1271.     stemp = self;
  1272.     self = other;
  1273.     best = W_BestWeapon();
  1274.         bbest = bot_bestweapon();
  1275.     self = stemp;
  1276.  
  1277. // change weapons
  1278.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1279.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1280.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1281.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1282.  
  1283.     other.items = other.items | self.items;
  1284.     
  1285.     bound_other_ammo ();
  1286.  
  1287.         if (other.classname == "player")
  1288.         {
  1289.                 sprint (other, "You get ");
  1290.         
  1291.                 if (self.ammo_shells)
  1292.                 {
  1293.                         s = ftos(self.ammo_shells);
  1294.                         sprint (other, s);
  1295.                         sprint (other, " shells  ");
  1296.                 }
  1297.                 if (self.ammo_nails)
  1298.                 {
  1299.                         s = ftos(self.ammo_nails);
  1300.                         sprint (other, s);
  1301.                         sprint (other, " nails ");
  1302.                 }
  1303.                 if (self.ammo_rockets)
  1304.                 {
  1305.                         s = ftos(self.ammo_rockets);
  1306.                         sprint (other, s);
  1307.                         sprint (other, " rockets  ");
  1308.                 }
  1309.                 if (self.ammo_cells)
  1310.                 {
  1311.                         s = ftos(self.ammo_cells);
  1312.                         sprint (other, s);
  1313.                         sprint (other, " cells  ");
  1314.                 }
  1315.     
  1316.                 sprint (other, "\n");
  1317. // backpack touch sound
  1318.                 sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1319.                 stuffcmd (other, "bf\n");
  1320.  
  1321. // change to a better weapon if appropriate
  1322.                 if ( other.weapon == best )
  1323.                 {
  1324.                         stemp = self;
  1325.                         self = other;
  1326.                         self.weapon = W_BestWeapon();
  1327.                         self = stemp;
  1328.                 }
  1329.                 remove(self);
  1330.     
  1331.                 self = other;
  1332.                 W_SetCurrentAmmo ();
  1333.         }
  1334.  
  1335.         if (other.classname == "bot")
  1336.         {
  1337.                 if (other.weapon == bbest)
  1338.                 {
  1339.                         stemp = self;
  1340.                         self = other;
  1341.                         self.weapon = bot_bestweapon();
  1342.                         self = stemp;
  1343.                 }
  1344.     
  1345.                 remove(self);
  1346.     
  1347.                 self = other;
  1348.                 bot_SetCurrentAmmo ();
  1349.         }
  1350. };
  1351.  
  1352. /*
  1353. ===============
  1354. DropBackpack
  1355. ===============
  1356. */
  1357. void() DropBackpack =
  1358. {
  1359.     local entity    item;
  1360.  
  1361.     if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1362.         return;    // nothing in it
  1363.  
  1364.     item = spawn();
  1365.     item.origin = self.origin - '0 0 24';
  1366.     
  1367.     item.items = self.weapon;
  1368.  
  1369.         self.classname = "backpack";
  1370.     item.ammo_shells = self.ammo_shells;
  1371.     item.ammo_nails = self.ammo_nails;
  1372.     item.ammo_rockets = self.ammo_rockets;
  1373.     item.ammo_cells = self.ammo_cells;
  1374.  
  1375.     item.velocity_z = 300;
  1376.     item.velocity_x = -100 + (random() * 200);
  1377.     item.velocity_y = -100 + (random() * 200);
  1378.     
  1379.     item.flags = FL_ITEM;
  1380.         item.solid = SOLID_TRIGGER;
  1381.         item.classname = "backpack";
  1382.     item.movetype = MOVETYPE_TOSS;
  1383.     setmodel (item, "progs/backpack.mdl");
  1384.     setsize (item, '-16 -16 0', '16 16 56');
  1385.     item.touch = BackpackTouch;
  1386.     
  1387.     item.nextthink = time + 120;    // remove after 2 minutes
  1388.     item.think = SUB_Remove;
  1389. };
  1390.